package com.rose.redis._data_structure.hash;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;

/**
 * Redis的Hash
 * 一：类似于Java里面的HashMap，都是 数组+链表。key2 = value2，key3 = value3可以看成是由于Hash冲突，而将数据追加到链表上。
 * hashKey ---> key1 = value1
 *              key2 = value2
 *              key3 = value3
 *
 * 二：语法：
 * 语法：hset hashkey value(key value)：向Hash中存入变量值
 * e.g：hset people name zhu
 * ==> 1
 *
 * 语法：hget hashkey value(key)：取出Hash中的key值
 * e.g：hget people name
 * ==> zhu
 *
 * 总结：可以使用Hash存储对象，存储方式如下。
 *
 * 三：常用命令
 * 1：hset [key] [field] [value]：新建字段信息。
 * 2：hget [key] [field]：获取字段信息。
 * 3：hdel [key] [field]：删除字段。
 * 4：hlen [key]：保存的字段个数。
 * 5：hgetall [key]：获取指定key字典里的所有字段和值（字段信息过多,会导致慢查询 慎用：亲身经历 曾经用过这个这个指令导致线上服务故障）。
 * 6：hmset [key] [field1] [value1] [field2] [value2] ......：批量创建。
 * 7：hincr [key] [field]：对字段值自增。
 * 8：hincrby [key] [field] [number]：对字段值增加number。
 *
 * @author: zhu.chen
 * @date: 2021/1/5
 * @version: v1.0.0
 */
//@Component
public class TestHashCommandLineRunner implements CommandLineRunner {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void run(String... args) throws Exception {
        People people = new People("zhangsan", 11);
        List<Field> fieldList = Arrays.asList(People.class.getDeclaredFields());
        for (Field field : fieldList) {
            field.setAccessible(true);
            String fieldName = field.getName();
            System.out.println(fieldName);
            Object fieldValue = field.get(people);
            System.out.println(fieldValue);
            redisTemplate.opsForHash().put(People.class.getName(), fieldName, fieldValue);
        }
    }

    @Configuration
    public static class TestListCommandLineRunnerConfig {

        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            redisTemplate.setKeySerializer(RedisSerializer.json());
            redisTemplate.setValueSerializer(RedisSerializer.json());
            redisTemplate.setHashKeySerializer(RedisSerializer.json());
            redisTemplate.setHashValueSerializer(RedisSerializer.json());
            return redisTemplate;
        }

    }

}
